import time
import matplotlib as mpl
from sklearn import metrics
from sklearn.metrics.pairwise import pairwise_distances_argmin
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import KMeans,MiniBatchKMeans

# 设置属性防止中文乱码
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False

def run():
    centers=[[1,1],[-1,-1],[-1,1]]
    clusters=len(centers)
    X,Y=make_blobs(n_samples=3000, centers=clusters, cluster_std=0.7,random_state=28)
    #Y 在实际工作中是人工给定的，专门用于判断聚类的效果的一个值
    km=KMeans(n_clusters=clusters, init='k-means++',random_state=28)
    t0=time.time()
    km.fit(X)
    km_len=time.time()-t0
    print ("K-Means算法模型训练消耗时间:%.4fs" % km_len)
    
    batch_size=100
    mkm=MiniBatchKMeans(n_clusters=clusters,init='k-means++',batch_size=batch_size,random_state=28)
    t0=time.time()
    mkm.fit(X)
    mkm_len=time.time()-t0
    print ("Mini Batch K-Means算法模型训练消耗时间:%.4fs" % mkm_len)
    # 样本所属的类别
    km_labels=km.labels_
    mkm_labels=mkm.labels_
    print("K-Means样本所属的类别:",km_labels)
    print("MiniBatchKMeans样本所属的类别:",mkm_labels)
    km_cluster_centers=km.cluster_centers_
    mkm_cluster_centers=mkm.cluster_centers_
    print ("K-Means算法聚类中心点:\ncenter=", km_cluster_centers)
    print ("Mini Batch K-Means算法聚类中心点:\ncenter=", mkm_cluster_centers)
    order=pairwise_distances_argmin(km_cluster_centers,mkm_cluster_centers)
    ### 效果评估
    score_funcs=[
        metrics.adjusted_rand_score, #ARI
        metrics.v_measure_score, #均一性和完整性的加权平均
        metrics.adjusted_mutual_info_score, #AMI
        metrics.mutual_info_score, #互信息
    ]
    
    #2. 迭代对每个评估函数进行评估操作
    for score_func in score_funcs:
        t0=time.time()
        km_scores=score_func(Y,km_labels)
        print("K-Means算法:%s评估函数计算结果值:%.5f；计算消耗时间:%0.3fs" % (score_func.__name__,km_scores, time.time() - t0))
        
        t0=time.time()
        mkm_scores=score_func(Y,mkm_labels)
        print("Mini Batch K-Means算法:%s评估函数计算结果值:%.5f；计算消耗时间:%0.3fs\n" % (score_func.__name__,mkm_scores, time.time() - t0))
     
        
run()